package com.originskyseed.platform.cms.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.originskyseed.platform.cms.mapper.CmsCatalogMapper;
import com.originskyseed.platform.cms.model.CmsCatalog;
import com.originskyseed.platform.cms.service.ICmsCatalogService;
import com.originskyseed.platform.core.base.BasePage;
import com.originskyseed.platform.core.tenant.util.TenantCodeUtil;
import com.originskyseed.platform.core.util.bean.PrimaryKeyGeneratorUtil;

/**
 * 内容目录接口实现类
 *
 * @author LiangMingHui
 *
 */
@DubboService
@Component("cmsCatalogService")
public class CmsCatalogServiceImpl implements ICmsCatalogService {

	@Resource
	private CmsCatalogMapper cmsCatalogMapper;

	/**
	 * deleteByPrimaryKey
	 *
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@Override
	public int deleteByPrimaryKey(String id) throws Exception {
		return this.cmsCatalogMapper.deleteByPrimaryKey(id);
	}

	/**
	 * deleteByPrimaryKeys
	 *
	 * @param ids
	 * @return
	 * @throws Exception
	 */
	@Override
	public int deleteByPrimaryKeys(List<String> ids) throws Exception {
		return this.cmsCatalogMapper.deleteByPrimaryKeys(ids);
	}

	/**
	 * insert
	 *
	 * @param record
	 * @return
	 * @throws Exception
	 */
	@Override
	public int insert(CmsCatalog record) throws Exception {
		if (StringUtils.isBlank(record.getId())) {
			record.setId(PrimaryKeyGeneratorUtil.getInstance().getRandomKey());
		}
		record.setCreateTime(new Date());
		return this.cmsCatalogMapper.insert(record);
	}

	/**
	 * insertSelective
	 *
	 * @param record
	 * @return
	 * @throws Exception
	 */
	@Override
	public int insertSelective(CmsCatalog record) throws Exception {
		if (StringUtils.isBlank(record.getId())) {
			record.setId(PrimaryKeyGeneratorUtil.getInstance().getRandomKey());
		}
		record.setCreateTime(new Date());
		return this.cmsCatalogMapper.insertSelective(record);
	}

	/**
	 * selectByPrimaryKey
	 *
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@Override
	public CmsCatalog selectByPrimaryKey(String id) throws Exception {
		return this.cmsCatalogMapper.selectByPrimaryKey(id);
	}

	/**
	 * selectByPrimaryKey
	 *
	 * @param id
	 * @param tenantCode
	 * @return
	 * @throws Exception
	 */
	@Override
	public CmsCatalog selectByPrimaryKey(String id, String tenantCode) throws Exception {
		if (StringUtils.isNotEmpty(tenantCode)) {
			TenantCodeUtil.getInstance().createServerTenantCode(tenantCode);
		}
		return this.cmsCatalogMapper.selectByPrimaryKey(id);
	}

	/**
	 * updateByPrimaryKeySelective
	 *
	 * @param record
	 * @return
	 * @throws Exception
	 */
	@Override
	public int updateByPrimaryKeySelective(CmsCatalog record) throws Exception {
		record.setUpdateTime(new Date());
		return this.cmsCatalogMapper.updateByPrimaryKeySelective(record);
	}

	/**
	 * updateByPrimaryKey
	 *
	 * @param record
	 * @return
	 * @throws Exception
	 */
	@Override
	public int updateByPrimaryKey(CmsCatalog record) throws Exception {
		record.setUpdateTime(new Date());
		return this.cmsCatalogMapper.updateByPrimaryKey(record);
	}

	/**
	 * 获取消息目录树
	 *
	 * @return
	 * @throws Exception
	 */
	@Override
	public JSONArray selectCmsCatalogTree(Map<String, Object> params) throws Exception {
		JSONArray result = new JSONArray();

		// 获取所有消息目录列表
		List<CmsCatalog> cmsCatalogList = this.cmsCatalogMapper.selectAllCmsCatalogs(params);

		// 追加消息树节点
		for (CmsCatalog cmsCatalog : cmsCatalogList) {
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("id", cmsCatalog.getId());
			jsonObject.put("pid", cmsCatalog.getParentId());
			jsonObject.put("name", cmsCatalog.getNameCn());
			jsonObject.put("code", cmsCatalog.getCmsCataCode());
			if ("0".equals(cmsCatalog.getId())) {
				jsonObject.put("open", true);
			} else {
				jsonObject.put("open", false);
			}
			result.add(jsonObject);
		}
		return result;
	}

	/**
	 * 分页查询消息目录
	 *
	 * @param params
	 * @param page
	 * @return
	 * @throws Exception
	 */
	@Override
	public BasePage<CmsCatalog> selectListByPage(Map<String, Object> params, BasePage<CmsCatalog> page) throws Exception {
		params.put("page", page);
		List<CmsCatalog> list = this.cmsCatalogMapper.selectListByPage(params);
		page.setResults(list);
		return page;
	}

	/**
	 * 查询消息目录
	 *
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<CmsCatalog> selectList(Map<String, Object> params) throws Exception {
		return this.cmsCatalogMapper.selectList(params);
	}

	/**
	 * 根据code查询目录 *
	 *
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<CmsCatalog> selectCmsCatalogByCmsCataCode(Map<String, Object> params) throws Exception {
		return this.cmsCatalogMapper.selectCmsCatalogByCmsCataCode(params);
	}

	/**
	 * 是否存在消息目录
	 *
	 * @param record
	 * @return
	 * @throws Exception
	 */
	@Override
	public Boolean existCode(CmsCatalog record) throws Exception {
		return this.cmsCatalogMapper.existCode(record);
	}

	/**
	 * 查询所有二级目录
	 *
	 * @return
	 * @throws Exception
	 */
	/*
	 * @Override public List<CmsCatalog> selectSecondlevelList() throws Exception { return this.cmsCatalogMapper.selectSecondlevelList(); }
	 */

	/**
	 * 查询三级目录
	 *
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<CmsCatalog> selectThirdlevelList(String id) throws Exception {
		return this.cmsCatalogMapper.selectThirdlevelList(id);
	}

	/**
	 * 根据父ID查找子类列表
	 *
	 * @param parentId
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<CmsCatalog> selectByParentId(String parentId) throws Exception {
		return this.cmsCatalogMapper.selectByParentId(parentId);
	}

	@Override
	public JSONArray selectCmsCatalogTreeList(Map<String, Object> params) throws Exception {
		// 获取所有消息目录列表
		List<CmsCatalog> cmsCatalogList = this.cmsCatalogMapper.selectAllCmsCatalogs(params);
		List<CmsCatalog> parentList = new ArrayList<>();
		for (CmsCatalog cmsCatalog : cmsCatalogList) {
			if (StringUtils.isBlank(cmsCatalog.getParentId())) {
				parentList.add(cmsCatalog);
			}
		}
		for (CmsCatalog topc : parentList) {
			cmsCatalogList.remove(topc);
		}

		// 递归构建
		return build2Tree(cmsCatalogList, parentList);
	}

	@Override
	public List<CmsCatalog> selectByOneLevelList(String mallId) throws Exception {
		return this.cmsCatalogMapper.selectByOneLevelList(mallId);
	}

	@Override
	public int copyCmsCatalogTemplate(Map<String, Object> params) throws Exception {
		List<CmsCatalog> cmsCatalogList = this.cmsCatalogMapper.selectAllCmsCatalogs(params);
		// 先删除商城下所有的目录，再复制模板
		for (CmsCatalog cmsCatalog : cmsCatalogList) {
			this.cmsCatalogMapper.deleteByPrimaryKey(cmsCatalog.getId());
		}
		Map<String, Object> map = new HashMap<>();
		map.put("isSys", 0);
		map.put("mallId", "template");
		// 模板目录
		List<CmsCatalog> cmsCatalogsTemplate = this.cmsCatalogMapper.selectAllCmsCatalogs(map);

		List<CmsCatalog> parentList = new ArrayList<>();
		for (CmsCatalog cms : cmsCatalogsTemplate) {
			if (StringUtils.isBlank(cms.getParentId())) {
				cms.setMallId(params.get("mallId").toString());
				parentList.add(cms);
				break;
			}
		}
		for (CmsCatalog topc : parentList) {
			cmsCatalogList.remove(topc);
		}
		List<CmsCatalog> insertCmsList = new ArrayList<>();
		insertCmsList = buildInsertCmsList(cmsCatalogsTemplate, parentList, parentList.get(0), insertCmsList);
		for (CmsCatalog cmsCatalog : insertCmsList) {
			this.cmsCatalogMapper.insertSelective(cmsCatalog);
		}
		return 0;
	}

	private List<CmsCatalog> buildInsertCmsList(List<CmsCatalog> list, List<CmsCatalog> parentList, CmsCatalog parentCms, List<CmsCatalog> insertCmsList) {
		if (!list.isEmpty() && !parentList.isEmpty()) {
			// 移除父节点
			list.removeAll(parentList);
			List<CmsCatalog> childList;
			for (CmsCatalog cms : parentList) {
				CmsCatalog insertCms = new CmsCatalog();
				BeanUtils.copyProperties(cms, insertCms);
				insertCms.setId(PrimaryKeyGeneratorUtil.getInstance().getRandomKey());
				insertCms.setMallId(parentCms.getMallId());
				insertCms.setIsSys(0);
				insertCms.setCreateTime(new Date());
				if (cms.getParentId() != null) {
					insertCms.setParentId(parentCms.getId());
				}
				insertCmsList.add(insertCms);
				// 查找子节点
				childList = findChildren(list, cms);
				if (hasChildren(childList)) {
					buildInsertCmsList(list, childList, insertCms, insertCmsList);
				}
			}
		}
		return insertCmsList;
	}

	/**
	 * 构建树 一次性查出所有数据，效率高
	 *
	 * @param list       包含所有数据
	 * @param parentList 只包含根节点或父节点数据
	 * @return
	 */
	private JSONArray build2Tree(List<CmsCatalog> list, List<CmsCatalog> parentList) {
		JSONArray ary = new JSONArray();
		if (!list.isEmpty() && !parentList.isEmpty()) {
			JSONObject obj;
			// 移除父节点
			list.removeAll(parentList);
			List<CmsCatalog> childList;
			for (CmsCatalog cms : parentList) {
				obj = new JSONObject();
				obj.put("id", cms.getId());
				obj.put("code", cms.getCmsCataCode());
				obj.put("name", cms.getNameCn());
				obj.put("parentId", cms.getParentId());
				// 查找子节点
				childList = findChildren(list, cms);
				if (hasChildren(childList)) {
					obj.put("children", build2Tree(list, childList));
				}
				ary.add(obj);
			}
		}
		return ary;
	}

	/**
	 * 查找当前父节点下的子节点数据
	 *
	 * @param list       去除父节点的所有数据
	 * @param cmsCatalog 父节点
	 * @return
	 */
	private List<CmsCatalog> findChildren(List<CmsCatalog> list, CmsCatalog cmsCatalog) {
		List<CmsCatalog> childList = new ArrayList<CmsCatalog>();
		if (!list.isEmpty()) {
			for (CmsCatalog cms : list) {
				if (cms.getParentId().equals(cmsCatalog.getId())) {
					childList.add(cms);
				}
			}
		}
		return childList;
	}

	/**
	 * 判断是否含有子节点
	 *
	 * @param list
	 * @return
	 */
	private boolean hasChildren(List<CmsCatalog> list) {
		return list.size() > 0 ? true : false;
	}
}
